home *** CD-ROM | disk | FTP | other *** search
- *************************
- * HappyENV-Handler *
- * 1.0 05.06.97 *
- * (C) Martin Gierich *
- *************************
-
-
- * Do not use this source code or parts of it in other programs !
- * See documentation about Copyright&Disclaimer.
- * Sorry about the not so well commented source.
-
-
- * Switches for options, enabled if label is defined,
- * disabled if semicolon is put in front of it.
-
- ;DEBUG = 1 ;allow debugging output via sushi (RawPutChar)
- ;VERBOSE = 1 ;verbose debug output
- ;EXPAND = 1
-
-
- INCDIR source:stripinc/
- INCLUDE exec/exec_lib.i
- INCLUDE dos/dos_lib.i
- INCLUDE dos/dosextens.i
- INCLUDE dos/filehandler.i
- INCLUDE dos/notify.i
- INCLUDE dos/rdargs.i
- INCLUDE debug.i
-
- * macro for calling OS routines
-
- CALL MACRO
- jsr _LVO\1(a6)
- ENDM
-
- * other macros
- * compare both operands and store minimum in the right one
- * third argument is label name
-
- MIN MACRO
- cmp.l \2,\1
- bhs.s .\3
- move.l \1,\2
- .\3 nop
- ENDM
-
- * miscellaneous definitions
-
- LF = 10
- mn_Node = 0
- lib_Version = 20
- _LVOToUpper = -174
- _LVOEasyRequestArgs = -588
- DOS_TRUE = -1
- DOS_FALSE = 0
- MEMF_CLEAR = $10000
- MAXPATH = 120
- MAXNAME = 32
- BLOCKSIZE = 5000
-
- * EasyRequest structure (Intuition)
- RSRESET
- es_StructSize RS.L 1
- es_Flags RS.L 1
- es_Title RS.L 1
- es_TextFormat RS.L 1
- es_GadgetFormat RS.L 1
- es_SIZEOF RS.W 0
-
-
- * notify list node structure
- RSRESET
- myn_Link RS.L 1
- myn_Request RS.L 1 ;notify-request
- myn_Key RS.L 1 ;pointer to file
- myn_Name RS.B 0 ;path/file name (dynamic)
-
- * lock structure for Lock() and open files
- RSRESET
- myl_Link RS.L 1
- myl_Key RS.L 1
- myl_Access RS.L 1
- myl_Task RS.L 1
- myl_Volume RS.L 1
- myl_Pos RS.L 1 ;position in file (read/write)
- myl_Data RS.L 1 ;start of file data (read)
- myl_Start RS.L 1 ;start of block list (write)
- myl_Block RS.L 1 ;current block (write)
- myl_BlockPos RS.L 1 ;position in current block (write)
- myl_Size RS.L 1 ;size of file
- myl_Mode RS.B 1 ;0=simple lock, -1=write, 1=read
- myl_Pad RS.B 1
- myl_SIZEOF RS.W 0
-
- * structure for file or dir
- RSRESET
- myf_Link RS.L 1 ;next file/dir
- myf_Parent RS.L 1 ;parent dir (root: 0)
- myf_First RS.L 0 ;dir: points to first entry
- myf_Size RS.L 1 ;file: size of filedata
- myf_Type RS.B 1 ;bit7: dir/file, 6:hidden, 5:copied,
- ;4:notify
- myf_Locks RS.B 1 ;number of locks, -1=write lock
- myf_DataOffs RS.B 1 ;offset to start of data
- myf_Name RS.W 0 ;name (dynamic), then data
-
- * private main structure
- RSRESET
- CharTable RS.B 256
- DosBase RS.L 1
- IntuiBase RS.L 1
- MyProcess RS.L 1
- MyMsgPort RS.L 1
- MyMemPool RS.L 1
- MyDeviceNode RS.L 1
- MyVolumeBPTR RS.L 1
- NotifyList RS.L 1
- Copyfrom RS.L 1
- CopyfromLock RS.L 1
- CopyfromPort RS.L 1
- RootLock RS.L 1
- StartDate RS.B ds_SIZEOF
- MyPacket RS.B sp_SIZEOF
- VolumeNode RS.B DevList_SIZEOF
- VolumeName RS.B MAXNAME
- NotifyPort RS.B MP_SIZE
- PacketPort RS.B MP_SIZE
- FileSize RS.L 1
- TotalSize RS.L 1
- NumLocks RS.L 1
- Kickver RS.W 1
- WriteProtected RS.B 1
- NSignal RS.B 1
- PSignal RS.B 1
- Paddy1 RS.B 1
- RootDir RS.B myf_Name+8
- Paddy2 RS.B 3
- TempPath RS.B MAXPATH
- TempName RS.B MAXNAME
- ReqStruct RS.B es_SIZEOF
- FormatArgs RS.L 2
- StupVolname RS.L 1
- StupIcon RS.B 1
- StupNocopy RS.B 1
- StupNoreq RS.B 1
- StupExpand RS.B 1
- My_SIZEOF RS.W 0
-
- MyPkt = MyPacket+sp_Pkt
-
- *******************************************************
-
- *******************************************************
-
- * common register usage:
- * a4=DOSpacket
- * a5=private struct
- * a6=execbase
-
- start: movem.l d2-d7/a2-a6,-(sp) ;do some basic inits
- move.l 4.w,a6
- move.l #My_SIZEOF,d0
- move.l #MEMF_CLEAR!1,d1
- CALL AllocMem
- tst.l d0
- beq exit1
- move.l d0,a5
- DBUG1 txstart,a5
- lea dosname(pc),a1
- moveq #33,d0
- CALL OpenLibrary
- move.l d0,DosBase(a5)
- beq exit2
- move.l d0,a2
- CALL Forbid
- move.l dl_Root(a2),a0
- lea rn_Time(a0),a0
- lea StartDate(a5),a1
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0),(a1)
- CALL Permit
- move.w lib_Version(a6),Kickver(a5)
- sub.l a1,a1
- CALL FindTask
- move.l d0,MyProcess(a5)
- cmp.w #36,Kickver(a5)
- blo.s .OS13
- move.l d0,a0
- bset #0,pr_Flags+3(a0)
- .OS13 add.l #pr_MsgPort,d0
- move.l d0,MyMsgPort(a5)
- ; clr.b RootDir+myf_Type(a5)
- cmp.w #39,Kickver(a5)
- blo.s .OS20
- moveq #1,d0
- move.l #5000,d1
- move.l #2000,d2
- CALL CreatePool
- move.l d0,MyMemPool(a5)
-
- .OS20 move.l MyMsgPort(a5),a2 ;process startup message
- bsr GetPacket
- move.l d0,a4
- move.l dp_Arg3(a4),d0
- lsl.l #2,d0
- move.l d0,MyDeviceNode(a5)
- move.l d0,a0
- move.l MyMsgPort(a5),dn_Task(a0)
- clr.l dn_SegList(a0)
- move.l dn_Name(a0),a0
- lea RootDir+myf_Name(a5),a1
- moveq #6,d0
- bsr CopyBSTR2Char
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- bsr ReplyPacket
-
- inireq: lea intuiname(pc),a1 ;init "unknown packet" requester
- moveq #36,d0
- CALL OpenLibrary
- move.l d0,IntuiBase(a5)
- beq.s .A
- lea ReqStruct(a5),a0
- moveq #es_SIZEOF,d0
- move.l d0,(a0)+
- clr.l (a0)+
- lea reqtitle(pc),a1
- move.l a1,(a0)+
- clr.l (a0)+
- lea reqbutton(pc),a1
- move.l a1,(a0)+
- .A
-
- args: move.l MyDeviceNode(a5),a1
- move.l dn_Startup(a1),a0
- clr.l dn_Startup(a1)
- move.l a0,d0
- beq .A
- lea TempPath(a5),a1
- move.l a1,a2
- moveq #MAXPATH-1,d0
- bsr CopyBSTR2Char
- moveq #DOS_RDARGS,d1
- moveq #0,d2
- move.l DosBase(a5),a6
- CALL AllocDosObject
- move.l d0,d3
- beq .A
- move.l a2,a0
- .D move.b (a0)+,d0
- beq.s .C
- cmp.b #"_",d0
- bne.s .D
- move.b #" ",-1(a0)
- bra.s .D
- .C move.b #LF,-1(a0)
- clr.b (a0)
- sub.l a2,a0
- lea TempName(a5),a3
- move.l a3,d2 ;Argument-Array
- clr.l (a3)+ ;clear it
- clr.l (a3)+
- clr.l (a3)+
- clr.l (a3)
- move.l d2,a3
- move.l d3,a1 ;Rd-Args-Struct
- move.l a2,(a1)+ ;CSource.Buffer
- move.l a0,(a1) ;CSource.Length
- lea template(pc),a0
- move.l a0,d1 ;Template
- CALL ReadArgs ;process Startup line
- DBUG4 txargs,(a3),4(a3),8(a3),12(a3)
- move.l d0,d2
- bne.s .E
- bsr RequestReadArgs
- bra.s .A
- .E move.l (a3)+,d0
- beq.s .G
- move.l d0,a0
- lea VolumeName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyChar2BSTR
- move.l d0,StupVolname(a5)
- .G lea StupIcon(a5),a0
- move.l (a3)+,d0
- move.b d0,(a0)+
- move.l (a3)+,d0
- move.b d0,(a0)+
- move.l (a3)+,d0
- move.b d0,(a0)+
- move.l d2,d1
- CALL FreeArgs
- moveq #DOS_RDARGS,d1
- move.l d3,d2
- CALL FreeDosObject
- .A move.l 4.w,a6
-
- volnod: lea VolumeNode(a5),a2 ;set up volume node
- move.l a2,d0
- lsr.l #2,d0
- move.l d0,MyVolumeBPTR(a5)
- moveq #2,d0
- move.l d0,dl_Type(a2)
- move.l MyMsgPort(a5),dl_Task(a2)
- move.l #"DOS"<<8,dl_DiskType(a2)
- lea volname1(pc),a0
- tst.b StupIcon(a5)
- beq.s .A
- move.l DosBase(a5),a0
- move.l dl_Root(a0),a0
- move.l rn_Info(a0),a0
- add.l a0,a0
- add.l a0,a0
- move.l di_DevInfo(a0),d0
- move.l d0,VolumeNode(a5)
- move.l MyVolumeBPTR(a5),di_DevInfo(a0)
- lea volname2(pc),a0
- .A move.l StupVolname(a5),d0
- bne.s .C
- lea VolumeName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyChar2BSTR
- .C move.l d0,dl_Name(a2)
-
- upconv: bsr InitConversion ;init upper case table
- lea NotifyPort(a5),a2 ;create msgport for notify
- move.b #NT_MSGPORT,LN_TYPE(a2)
- moveq #-1,d0
- CALL AllocSignal
- tst.l d0
- bmi exit3
- move.b d0,NSignal(a5)
- move.b d0,MP_SIGBIT(a2)
- move.l MyProcess(a5),MP_SIGTASK(a2)
- lea MP_MSGLIST(a2),a0
- move.b #NT_MESSAGE,LH_TYPE(a0)
- NEWLIST a0
- lea PacketPort(a5),a2 ;create msgport for DOSpackets
- move.b #NT_MSGPORT,LN_TYPE(a2)
- moveq #-1,d0
- CALL AllocSignal
- tst.l d0
- bmi exit3
- move.b d0,PSignal(a5)
- move.b d0,MP_SIGBIT(a2)
- move.l MyProcess(a5),MP_SIGTASK(a2)
- lea MP_MSGLIST(a2),a0
- move.b #NT_MESSAGE,LH_TYPE(a0)
- NEWLIST a0
- lea RootDir(a5),a2 ;create Lock for DiskInfo
- moveq #ACCESS_READ,d2
- bsr CreateLock
- move.l d0,RootLock(a5)
- beq exit4
-
- auto: tst.b StupNocopy(a5) ;init autocopy
- bne.s .A
- CALL Forbid
- move.l DosBase(a5),a0
- move.l dl_Root(a0),a0
- move.l rn_Info(a0),a0
- add.l a0,a0
- add.l a0,a0
- lea di_DevInfo(a0),a2
- .C move.l (a2),d0
- beq.s .D
- lsl.l #2,d0
- move.l d0,a2
- move.l dol_Name(a2),a0
- add.l a0,a0
- add.l a0,a0
- lea sysdisk(pc),a1
- moveq #0,d0
- move.b (a0)+,d0
- bra.s .F
- .G move.b (a1)+,d1
- cmp.b (a0)+,d1
- bne.s .C
- .F dbra d0,.G
- tst.b (a1)
- bne.s .C
- CALL Permit
- move.l a2,Copyfrom(a5)
- DBUG1 txcopy,Copyfrom(a5)
- bra.s .A
- .D CALL Permit
- .A
-
- loop: move.l MyMsgPort(a5),a2 ;enter main loop
- bsr GetPacket
- move.l d0,a4
- bsr GetNotify
- clr.l dp_Res1(a4)
- clr.l dp_Res2(a4)
- move.l dp_Type(a4),d0
- IFD DEBUG
- move.l dp_Port(a4),a1
- move.l MP_SIGTASK(a1),a1
- move.l LN_NAME(a1),a1
- DBUG5 txpack,d0,dp_Arg1(a4),dp_Arg2(a4),dp_Arg3(a4),a1
- ENDC
- move.l d0,d1
- swap d1
- tst.w d1
- bne.s .A
- lea start(pc),a1
- lea JumpTable(pc),a2
- moveq #0,d2
- .C move.w (a2)+,d1
- bpl.s .E
- .A DBUG1 txerr1,d0
- bsr RequestUnknown
- move.w #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
- bra.s .D
- .E move.w (a2)+,d2
- cmp.w d0,d1
- bne.s .C
- add.l d2,a1
- ;***
- jsr (a1) ;jump into subroutine to process packet
- ;***
- .D IFD DEBUG
- moveq #DOS_TRUE,d0
- cmp.l dp_Res1(a4),d0
- beq.s .H
- DBUG2 txres,dp_Res1(a4),dp_Res2(a4)
- .H ENDC
- bsr ReplyPacket
- bra loop
-
- AExit: addq.l #4,sp ;exit routine
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- bsr ReplyPacket
- IFND DEBUG
- move.l NumLocks(a5),d0
- subq.l #1,d0
- bne loop
- ENDC
- move.l RootLock(a5),a1
- bsr FreeLock
- exit4: move.l MyDeviceNode(a5),a0
- clr.l dn_Task(a0)
- bsr FlushPackets
- tst.b StupIcon(a5)
- beq.s .A
- move.l DosBase(a5),a0
- move.l dl_Root(a0),a0
- move.l rn_Info(a0),a0
- add.l a0,a0
- add.l a0,a0
- move.l VolumeNode(a5),d0
- move.l d0,di_DevInfo(a0)
-
- .A moveq #0,d0
- move.b PSignal(a5),d0
- CALL FreeSignal
- moveq #0,d0
- move.b NSignal(a5),d0
- CALL FreeSignal
- exit3: move.l DosBase(a5),a1
- CALL CloseLibrary
- exit2: move.l MyDeviceNode(a5),a0
- clr.l dn_Task(a0)
- DBUG3 txend,FileSize(a5),TotalSize(a5),NumLocks(a5)
- move.l MyMemPool(a5),d0
- beq.s .A
- move.l d0,a0
- CALL DeletePool
- .A move.l a5,a1
- move.l #My_SIZEOF,d0
- CALL FreeMem
- exit1: movem.l (sp)+,d2-d7/a2-a6
- moveq #0,d0
- rts
-
- *******************************************************
-
- * table for branching from main to subroutine depending on the
- * current packet
-
- JumpTable:
- dc.w ACTION_NIL,NoAction-start
- dc.w ACTION_SET_PROTECT,Unsupported-start
- dc.w ACTION_SET_COMMENT,Unsupported-start
- dc.w ACTION_SET_DATE,Unsupported-start
- dc.w ACTION_INHIBIT,Unsupported-start
- dc.w ACTION_FLUSH,NoAction-start
- dc.w ACTION_IS_FILESYSTEM,NoAction-start
-
- dc.w ACTION_DIE,AExit-start
- dc.w ACTION_CURRENT_VOLUME,ACurrentVolume-start
- dc.w ACTION_RENAME_DISK,ARenameDisk-start
- dc.w ACTION_WRITE_PROTECT,AWriteProtect-start
-
- dc.w ACTION_FINDUPDATE,AOpenReadWrite-start
- dc.w ACTION_FINDINPUT,AOpenOldfile-start
- dc.w ACTION_FINDOUTPUT,AOpenNewfile-start
- dc.w ACTION_END,ACloseFile-start
- dc.w ACTION_SEEK,ASeekPosition-start
- dc.w ACTION_READ,AReadFile-start
- dc.w ACTION_WRITE,AWriteFile-start
- dc.w ACTION_DELETE_OBJECT,ADeleteObject-start
- dc.w ACTION_RENAME_OBJECT,ARenameObject-start
- dc.w ACTION_CREATE_DIR,ACreateDir-start
-
- dc.w ACTION_LOCATE_OBJECT,ALocateObject-start
- dc.w ACTION_PARENT,AParentDir-start
- dc.w ACTION_COPY_DIR,ADuplicateLock-start
- dc.w ACTION_FREE_LOCK,AFreeLock-start
- dc.w ACTION_SAME_LOCK,ASameLock-start
- dc.w ACTION_EXAMINE_OBJECT,AExamineObject-start
- dc.w ACTION_EXAMINE_ALL,Unsupported-start
- dc.w ACTION_EXAMINE_FH,AExamineFH-start
- dc.w ACTION_EXAMINE_ALL_END,Unsupported-start
- dc.w ACTION_EXAMINE_NEXT,AExamineNext-start
- dc.w ACTION_DISK_INFO,ADiskInfo1-start
- dc.w ACTION_INFO,ADiskInfo2-start
-
- dc.w ACTION_ADD_NOTIFY,AAddNotify-start
- dc.w ACTION_REMOVE_NOTIFY,ARemoveNotify-start
- dc.w ACTION_SET_FILE_SIZE,ASetFileSize-start
- dc.w ACTION_FH_FROM_LOCK,AFHfromLock-start
- dc.w ACTION_CHANGE_MODE,AChangeMode-start
- dc.w ACTION_COPY_DIR_FH,ADupLockFromFH-start
- dc.w ACTION_PARENT_FH,AParentFromFH-start
- dc.w -1
-
-
- * strings
-
- volname1 dc.b "Env",0
- volname2 dc.b "Environment",0
- intuiname dc.b "intuition.library",0
- reqtitle dc.b "HappyENV warning:",0
- requnknown dc.b "Task %s",LF,"uses packet %ld",0
- reqreadargs dc.b "Bad startup arguments",0
- reqbutton dc.b "Ok",0
- version dc.b "$VER: HappyENV-Handler 1.0 (05.06.97)",LF,0
- dosname dc.b "dos.library",0
- utilname dc.b "utility.library",0
- sysdisk dc.b "ENVARC",0
- template dc.b "VOLNAME/K,ICON/S,NOCOPY/S,NOREQ/S",0
- IFD EXPAND
- prefstx dc.b "prefs",0
- configtx dc.b "config",0
- ENDC
- even
-
- *******************************************************
-
- * Init to-upper-conversion table which allows
- * quick case independent compares
- InitConversion:
- lea CharTable(a5),a2
- move.w #255,d0
- .A move.b d0,0(a2,d0.w)
- dbra d0,.A
- moveq #"A",d0
- .C move.b d0,"a"-"A"(a2,d0.w)
- addq.w #1,d0
- cmp.b #"Z"+1,d0
- bne.s .C
- move.w #192,d0
- .F move.b d0,224-192(a2,d0.w)
- addq.w #1,d0
- cmp.b #222+1,d0
- bne.s .F
-
- lea utilname(pc),a1 ;open utility.library
- moveq #37,d0
- CALL OpenLibrary
- tst.l d0
- beq.s .D
- move.l d0,a6
- move.w #255,d2
- .E move.w d2,d0
- CALL ToUpper
- move.b d0,0(a2,d2.w)
- dbra d2,.E
- move.l a6,a1
- move.l 4.w,a6
- CALL CloseLibrary
- .D rts
-
- * Display requester for unknown packets
- RequestUnknown:
- tst.b StupNoreq(a5)
- bne.s .A
- move.l IntuiBase(a5),a6
- move.l a6,d0
- beq.s .A
- lea ReqStruct(a5),a1
- lea requnknown(pc),a0
- move.l a0,12(a1)
- sub.l a2,a2
- lea FormatArgs(a5),a3
- move.l dp_Type(a4),4(a3)
- move.l dp_Port(a4),a0
- move.l MP_SIGTASK(a0),a0
- move.l LN_NAME(a0),(a3)
- sub.l a0,a0
- CALL EasyRequestArgs
- move.l 4.w,a6
- .A rts
-
- * Display requester for bad startup arguments
- RequestReadArgs:
- move.l IntuiBase(a5),a6
- move.l a6,d0
- beq.s .A
- lea ReqStruct(a5),a1
- lea reqreadargs(pc),a0
- move.l a0,12(a1)
- sub.l a2,a2
- sub.l a3,a3
- sub.l a0,a0
- CALL EasyRequestArgs
- move.l 4.w,a6
- .A rts
-
- * Wait for a packet, then get it
- * ENTRY: a2=msgport
- * EXIT: d0=packet
- GetPacket:
- .A move.l a2,a0
- CALL WaitPort
- move.l a2,a0
- CALL GetMsg
- tst.l d0
- beq.s .A
- move.l d0,a0
- move.l mn_Node+LN_NAME(a0),d0
- beq.s .A
- rts
-
- * Reply packet in a4
- ReplyPacket:
- move.l a4,a2
- move.l dp_Port(a4),a0 ;reply port
- move.l MyMsgPort(a5),dp_Port(a2)
- * More general reply packet
- * ENTRY: a2=packet to send, a0=msgport to send to
- SendPacket:
- move.l dp_Link(a2),a1 ;message to send
- move.l a2,mn_Node+LN_NAME(a1)
- clr.l mn_Node+LN_SUCC(a1)
- clr.l mn_Node+LN_PRED(a1)
- move.b #NT_MESSAGE,mn_Node+LN_TYPE(a1)
- CALL PutMsg
- rts
-
- * Reply all packets that are waiting to be processed (for exit)
- FlushPackets:
- .A move.l MyMsgPort(a5),a0
- CALL GetMsg
- tst.l d0
- beq.s .C
- move.l d0,a0
- move.l mn_Node+LN_NAME(a0),d0
- beq.s .A
- move.l d0,a4
- clr.l dp_Res1(a4)
- move.w #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
- bsr ReplyPacket
- bra.s .A
- .C rts
-
- * Send a packet to the handler in CopyfromPort and wait for a reply
- * ENTRY: d0=dp_Type, d1=dp_Arg1, d2=dp_Arg2, d3=dp_Arg3
- * EXIT: d0=dp_Res1, d1=dp_Res2, Z-flag
- DoPacket:
- move.l a2,-(sp)
- lea MyPacket(a5),a1
- lea sp_Pkt(a1),a2
- move.l a1,dp_Link(a2)
- lea PacketPort(a5),a1
- move.l a1,dp_Port(a2)
- move.l d0,dp_Type(a2)
- move.l d1,dp_Arg1(a2)
- move.l d2,dp_Arg2(a2)
- move.l d3,dp_Arg3(a2)
- move.l CopyfromPort(a5),a0
- bsr SendPacket
- lea PacketPort(a5),a2
- bsr GetPacket
- move.l d0,a0
- DBUG4 txpkt,a0,dp_Type(a0),dp_Res1(a0),dp_Res2(a0)
- ; bsr wait_c
- move.l dp_Res2(a0),d1
- move.l dp_Res1(a0),d0
- move.l (sp)+,a2
- rts
-
- *******************************************************
-
- *******************************************************
-
-
- * Following there are all subroutines to process the individual packets
- * It starts with some general purpose and Filehandle handling ones.
-
- * No action will be performed
- NoAction:
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- rts
-
- * For unsupported packets without showing a requester
- Unsupported:
- DBUG1 txerr1,dp_Type(a4)
- move.w #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
- rts
-
- ACurrentVolume:
- move.l MyVolumeBPTR(a5),dp_Res1(a4)
- rts
-
- ARenameDisk:
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne.s .fail
- move.l dp_Arg1(a4),a0
- lea TempName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyBSTR2Char
- lea TempName(a5),a0
- lea VolumeName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyChar2BSTR
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- AWriteProtect:
- move.l dp_Arg1(a4),d0
- move.b d0,WriteProtected(a5)
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- rts
-
- AOpenReadWrite:
- move.l dp_Arg3(a4),a0
- move.l dp_Arg2(a4),d0
- moveq #ACCESS_READ,d2
- bsr LocateObject
- bne.s OpnOld
- bra.s AOpenNewfile
-
- AOpenOldfile:
- move.l dp_Arg3(a4),a0
- move.l dp_Arg2(a4),d0
- moveq #ACCESS_READ,d2
- bsr LocateObject
- OpnOld: move.l dp_Arg1(a4),a3 ;label used by AOpenReadWrite and AFHFromLock
- add.l a3,a3
- add.l a3,a3
- clr.l fh_Interactive(a3)
- move.l d0,fh_Arg1(a3)
- beq.s .fail
- move.l d0,a0
- move.l myl_Key(a0),a1
- move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
- tst.b myf_Type(a1) ;do not open dirs
- bmi.s .A
- move.l a0,a1
- bsr FreeLock
- bra.s .fail
- .A move.l myf_Size(a1),myl_Size(a0)
- moveq #0,d0
- move.b myf_DataOffs(a1),d0
- add.l d0,a1
- move.l a1,myl_Data(a0)
- move.b #1,myl_Mode(a0)
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- DBUG1 txopeno,fh_Arg1(a3)
- .fail rts
-
- AOpenNewfile:
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
- move.l dp_Arg1(a4),a3
- add.l a3,a3
- add.l a3,a3
- clr.l fh_Interactive(a3)
- move.l dp_Arg2(a4),d0 ;does file already exist ?
- move.l dp_Arg3(a4),a0
- bsr DelSearchObject
- beq.s .A
- move.l d0,a1
- tst.b myf_Type(a1) ;do not overwrite dirs
- bpl .fail
- bsr DeleteObject
- beq .fail
- .A bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
- move.l dp_Arg2(a4),d0
- bsr CreatePath
- beq .fail
- move.l a3,-(sp)
- move.l d0,a3
- lea TempName(a5),a2
- moveq #0,d2
- bsr CreateNewObject
- move.l (sp)+,a3
- beq.s .fail
- move.l d0,a2
- moveq #ACCESS_WRITE,d2
- bsr CreateLock
- move.l d0,fh_Arg1(a3)
- beq.s .fail
- move.l d0,a0
- move.b #-1,myl_Mode(a0)
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- DBUG1 txopenn,fh_Arg1(a3)
- .fail rts
-
- ACloseFile:
- move.l dp_Arg1(a4),a1
- tst.b myl_Mode(a1)
- bmi.s .D
- bsr FreeLock
- bra.s .ok
- .D move.l myl_Size(a1),d2
- move.l myl_Key(a1),a2
- move.l myf_Parent(a2),a3
- lea myf_Name(a2),a2
- bsr CreateNewObject
- beq.s .fail
- move.l d0,d4
- move.l d0,a3
- add.l d1,a3
- move.l dp_Arg1(a4),a2
- bsr CopyBlocksToMem
- move.l a2,a1
- move.l myl_Key(a2),a2
- bsr FreeLock
- move.l a2,a1
- bsr DeleteObj
- beq.s .fail
- move.l d4,a0
- bsr CheckNotify
- .ok moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- * Copy all blocks of a filehandle to memory
- * ENTRY: a2=lock, a3=destination memory
- * EXIT: nothing (some registers changed)
- * USED BY: ACloseFile, ASetFileSize
- CopyBlocksToMem:
- move.l myl_Start(a2),d3
- .F tst.l d3
- beq.s .A
- move.l d3,-(sp)
- move.l d3,a0
- move.l (a0)+,d3
- move.l (a0)+,d2
- move.l a3,a1
- move.l d2,d0
- CALL CopyMem
- add.l d2,a3
- move.l d2,d0
- addq.l #8,d0
- move.l (sp)+,a1
- bsr FreeMem
- bra.s .F
- .A rts
-
- AWriteFile:
- moveq #-1,d0
- move.l d0,dp_Res1(a4)
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.l dp_Arg1(a4),a2 ;lock
- move.l dp_Arg2(a4),a3 ;buffer
- move.l dp_Arg3(a4),d3 ;length
-
- bsr ReadToWriteMode
- beq .fail
- .F move.l d3,d2
- move.l myl_Block(a2),d0
- beq.s .E
- move.l d0,a1
- move.l 4(a1),d0
- sub.l myl_BlockPos(a2),d0
- beq.s .C
- bmi.s .C
- MIN d0,d2,G
- .D addq.l #8,a1
- add.l myl_BlockPos(a2),a1
- move.l a3,a0
- move.l d2,d0
- CALL CopyMem
- DBUG2 txwins,d2,myl_Pos(a2)
- add.l d2,a3
- add.l d2,myl_Pos(a2)
- add.l d2,myl_BlockPos(a2)
- sub.l d2,d3
- beq.s .ok
- bra.s .F
- .C move.l (a1),d0
- beq.s .E
- move.l d0,myl_Block(a2)
- clr.l myl_BlockPos(a2)
- bra.s .F
-
- .E bsr AppendNewBlock
- beq.s .fail
- clr.w dp_Res2+2(a4)
- move.l a3,a0
- move.l d3,d0
- CALL CopyMem
- add.l d3,myl_Pos(a2)
- move.l d3,myl_BlockPos(a2)
- .ok move.l dp_Arg3(a4),dp_Res1(a4)
- DBUG3 txwrite,dp_Arg3(a4),myl_Pos(a2),myl_Size(a2)
- .fail rts
-
- ASetFileSize:
- moveq #-1,d0
- move.l d0,dp_Res1(a4)
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.w #ERROR_SEEK_ERROR,dp_Res2+2(a4)
- move.l dp_Arg1(a4),a2 ;a2=lock
- move.l dp_Arg2(a4),d3 ;d3=position to truncate
- move.l dp_Arg3(a4),d2 ;d2=mode
- move.l myl_Size(a2),d4 ;d4=old size
- moveq #OFFSET_BEGINNING,d0
- cmp.l d0,d2
- beq.s .E
- moveq #OFFSET_END,d0
- cmp.l d0,d2
- bne.s .C
- add.l d4,d3
- bra.s .E
- .C moveq #OFFSET_CURRENT,d0
- cmp.l d0,d2
- bne .fail
- add.l myl_Pos(a2),d3
- .E DBUG2 txsize,myl_Key(a2),d4,d3
- tst.l d3 ;d3=new size
- bmi .fail
- cmp.l d4,d3
- beq.s .ok ;size will not change
- bhi.s .A ;append some data
-
- move.l d3,myl_Size(a2) ;truncate some data
- MIN d3,myl_Pos(a2),F
- bsr ReadToWriteMode
- beq.s .fail
- cmp.b #1,d0
- beq.s .ok
- move.l myl_Pos(a2),myl_BlockPos(a2)
- move.l d3,d0
- beq.s .D
- bsr CreateNewBlock
- beq.s .fail
- .D move.l myl_Start(a2),d4
- move.l d0,myl_Block(a2)
- move.l d0,myl_Start(a2)
- move.l a1,a3
- .J tst.l d4
- beq.s .ok
- move.l d4,-(sp)
- move.l d4,a0
- move.l (a0)+,d4
- move.l (a0)+,d2
- cmp.l d2,d3
- bls.s .G
- move.l d2,d0
- sub.l d2,d3
- bra.s .H
- .G move.l d3,d0
- beq.s .I
- moveq #0,d3
- .H move.l a3,a1
- CALL CopyMem
- .I add.l d2,a3
- move.l d2,d0
- addq.l #8,d0
- move.l (sp)+,a1
- bsr FreeMem
- bra.s .J
-
- .A bsr ReadToWriteMode ;append some data
- beq.s .fail
- sub.l d4,d3
- bsr AppendNewBlock
- beq.s .fail
- .ok move.l myl_Size(a2),dp_Res1(a4)
- .fail rts
-
-
- * Convert Lock from Read to Write mode
- * ENTRY: a2=lock
- * EXIT: d0,Z=success (0=fail, 1=changed, 2=not changed)
- * USED BY: AWriteFile, ASetFileSize
- ReadToWriteMode:
- moveq #2,d0
- tst.b myl_Mode(a2)
- bmi.s .ok
- move.w #ERROR_WRITE_PROTECTED,dp_Res2+2(a4)
- move.l myl_Key(a2),a0
- cmp.b #1,myf_Locks(a0)
- bhi.s .fail
- move.l myl_Size(a2),d0
- beq.s .A
- bsr CreateNewBlock
- beq.s .fail
- .A move.l d0,myl_Block(a2)
- move.l d0,myl_Start(a2)
- move.l myl_Pos(a2),myl_BlockPos(a2)
- move.b #-1,myl_Mode(a2)
- move.l myl_Key(a2),a0
- move.b #-1,myf_Locks(a0)
- move.l myl_Data(a2),a0
- move.l myl_Size(a2),d0
- beq.s .C
- CALL CopyMem
- .C DBUG2 txchng,myl_Key(a2),myl_Pos(a2),myl_Size(a2)
- moveq #1,d0
- .ok rts
- .fail moveq #0,d0
- rts
-
- * Create and append a new block as last one to block list
- * ENTRY: d3=size, a2=lock
- * EXIT: d0,Z=success, a1=newblock+8
- * USED BY: AWriteFile, ASetFileSize
- AppendNewBlock:
- move.l d3,d0
- bsr CreateNewBlock
- beq.s .fail
- add.l d3,myl_Size(a2)
- move.l myl_Block(a2),a0
- move.l d0,myl_Block(a2)
- move.l a0,d1
- bne.s .A
- lea myl_Start(a2),a0
- .A move.l (a0),d1 ;look for end of blocks
- beq.s .C ; for SetFileSize
- move.l d1,a0
- bra.s .A
- .C move.l d0,(a0) ;insert new block as last
- moveq #1,d0
- .fail rts
-
- * Allocates memory for a new block
- * ENTRY: d0=size
- * EXIT: d0=block , a1=block+8
- * USED BY: AppendNewBlock, ReadToWriteMode, ASetFileSIze
- CreateNewBlock:
- move.w #ERROR_DISK_FULL,dp_Res2+2(a4)
- move.l d0,-(sp)
- addq.l #8,d0
- bsr AllocMem
- beq.s .fail
- move.l d0,a1
- clr.l (a1)+
- move.l (sp),(a1)+
- .fail addq.l #4,sp
- tst.l d0
- rts
-
- AReadFile:
- move.l dp_Arg1(a4),a2 ;lock
- move.l dp_Arg2(a4),a3 ;buffer
- move.l myl_Size(a2),d0
- move.l myl_Pos(a2),a0
- sub.l a0,d0
- move.l dp_Arg3(a4),d3 ;length
- MIN d0,d3,G
- clr.w dp_Res2+2(a4)
- DBUG3 txread,d3,dp_Arg3(a4),myl_Pos(a2)
- add.l d3,myl_Pos(a2)
- move.l d3,dp_Res1(a4)
- beq.s .ok
- tst.b myl_Mode(a2)
- bpl.s .E
-
- .F move.l d3,d2
- move.l myl_Block(a2),a0
- move.l 4(a0),d0
- sub.l myl_BlockPos(a2),d0
- beq.s .C
- bmi.s .C
- MIN d0,d2,D
- addq.l #8,a0
- add.l myl_BlockPos(a2),a0
- move.l a3,a1
- move.l d2,d0
- CALL CopyMem
- add.l d2,a3
- add.l d2,myl_BlockPos(a2)
- sub.l d2,d3
- beq.s .ok
- bra.s .F
- .C move.l (a1),d0
- beq.s .ok
- move.l d0,myl_Block(a2)
- clr.l myl_BlockPos(a2)
- bra .F
-
- .E move.l myl_Data(a2),d0
- add.l d0,a0
- move.l a3,a1
- move.l d3,d0
- CALL CopyMem
- .ok rts
-
- ASeekPosition
- move.l dp_Arg1(a4),a2 ;a2=lock
- move.l dp_Arg2(a4),d1 ;d1=position
- move.l dp_Arg3(a4),d2 ;d2=mode
- clr.w dp_Res2+2(a4)
- move.l myl_Pos(a2),d3 ;d3=old pos
- move.l myl_Size(a2),d4 ;d4=size
-
- moveq #OFFSET_BEGINNING,d0
- cmp.l d0,d2
- beq.s .E
- moveq #OFFSET_END,d0
- cmp.l d0,d2
- bne.s .C
- add.l d4,d1
- bra.s .E
- .C moveq #OFFSET_CURRENT,d0
- cmp.l d0,d2
- bne.s .fail
- add.l d3,d1
- .E move.l d1,myl_Pos(a2)
- bmi.s .A
- cmp.l d1,d4
- bhs.s Seeek
- move.l d4,myl_Pos(a2)
- bra.s .fail
- .A clr.l myl_Pos(a2)
- .fail move.w #ERROR_SEEK_ERROR,dp_Res2+2(a4)
- moveq #-1,d3
-
- Seeek tst.b myl_Mode(a2) ;label not used globally
- bpl.s .A
- move.l myl_Pos(a2),d2
- move.l myl_Start(a2),d0
- beq.s .A
- bra.s .E
- .D move.l (a0),d0
- beq.s .C
- .E move.l d0,a0
- move.l 4(a0),d1
- sub.l d1,d2
- beq.s .F
- bpl.s .D
- .F add.l d1,d2
- .C move.l a0,myl_Block(a2)
- move.l d2,myl_BlockPos(a2)
- .A move.l d3,dp_Res1(a4)
- DBUG1 txseek,myl_Pos(a2)
- rts
-
- ADeleteObject:
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne.s .fail
- move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr SearchObject
- beq.s .fail
- movem.l d0-d1,-(sp)
- move.l d0,a0
- moveq #1,d0
- bsr NotifyObject
- movem.l (sp)+,d0-d1
- move.l d0,a1
- bsr DeleteObject
- beq.s .fail
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- ARenameObject:
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr SearchObject
- beq .fail
- move.l d0,a3
- move.l d1,d3
- move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
- tst.b myf_Locks(a3)
- bne .fail
- move.l a3,a0
- bsr NotifyObject
- move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
- move.l dp_Arg3(a4),d0
- move.l dp_Arg4(a4),a0
- bsr DelSearchObject
- bne .fail
- bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
- move.l dp_Arg3(a4),d0
- bsr SearchPath
- beq .fail
- move.l a3,-(sp)
- moveq #0,d2
- tst.b myf_Type(a3)
- bpl.s .D
- move.l myf_Size(a3),d2
- .D move.l d0,a3
- lea TempName(a5),a2
- bsr CreateNewObject
- move.l (sp)+,a3
- beq.s .fail
- move.l d0,a2
- move.b myf_Type(a3),myf_Type(a2)
- bpl.s .A
- move.l a2,a1 ;rename file
- add.l d1,a1
- move.l a3,a0
- moveq #0,d0
- move.b myf_DataOffs(a3),d0
- add.l d0,a0
- move.l myf_Size(a3),d0
- CALL CopyMem
- bra.s .C
- .A move.l myf_First(a3),d0 ;rename dir
- clr.l myf_First(a3)
- move.l d0,myf_First(a2)
- beq.s .C
- .E move.l d0,a0
- move.l a2,myf_Parent(a0)
- move.l myf_Link(a0),d0
- bne.s .E
- .C move.l d3,d1 ;end rename
- move.l a3,a1
- bsr DeleteObject
- beq.s .fail
- move.l a2,a0
- bsr CheckNotify
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- *******************************************************
-
- * Here are subroutines for packets that deal with Locks.
-
- ALocateObject:
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- move.l dp_Arg3(a4),d2
- bsr LocateObject
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- rts
-
- ADupLockFromFH:
- move.l dp_Arg1(a4),d0
- bra.s DupLock
-
- ADuplicateLock:
- move.l dp_Arg1(a4),d0
- lsl.l #2,d0
- DupLock beq.s .fail ;label not used globally
- move.l d0,a0
- move.l myl_Key(a0),a2
- moveq #ACCESS_READ,d2
- bsr CreateLock
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- AParentFromFH:
- move.l dp_Arg1(a4),d0
- bra.s ParentD
- AParentDir:
- move.l dp_Arg1(a4),d0
- lsl.l #2,d0
- ParentD beq.s .fail ;label not used globally
- move.l d0,a0
- move.l myl_Key(a0),a2
- move.l myf_Parent(a2),d0
- beq.s .fail
- move.l d0,a2
- moveq #ACCESS_READ,d2
- bsr CreateLock
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- AFreeLock:
- move.l dp_Arg1(a4),d0
- beq.s .fail
- lsl.l #2,d0
- move.l d0,a1
- bsr FreeLock
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- ASameLock:
- tst.b StupIcon(a5)
- bne Unsupported
- moveq #LOCK_SAME_VOLUME,d0
- move.l d0,dp_Res1(a4)
- move.l dp_Arg1(a4),a0
- add.l a0,a0
- add.l a0,a0
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- move.l myl_Key(a0),d0
- cmp.l myl_Key(a1),d0
- bne.s .A
- moveq #LOCK_SAME,d0
- move.l d0,dp_Res1(a4)
- .A rts
-
- AExamineFH:
- move.l dp_Arg1(a4),a0
- bra.s Exammi
-
- AExamineObject:
- move.l dp_Arg1(a4),a0
- add.l a0,a0
- add.l a0,a0
- Exammi move.l myl_Key(a0),a0 ;label not used globally
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- DBUG1 txexam,a0
- move.l a1,a2
- moveq #fib_SIZEOF/4-1,d0
- .D clr.l (a2)+
- dbra d0,.D
- * Fill FileInfoBlock (fib) with infos about the object
- * Used by AExamineFH, AExamineObject and AExamineNext
- * ENTRY: a0=file, a1=fib
- ExamineObject:
- moveq #1,d0
- tst.l myf_Parent(a0)
- beq.s .C ;rootdir ?
- IFD DEBUG
- btst #6,myf_Type(a0)
- beq.s .D ;hidden file ?
- moveq #-3,d0
- bra.s .C
- .D ENDC
- moveq #-3,d0
- tst.b myf_Type(a0)
- bmi.s .C ;file ?
- moveq #2,d0 ;dir
- .C moveq #0,d1
- move.l d0,fib_DirEntryType(a1)
- move.l d0,fib_EntryType(a1)
- bpl.s .A
- move.l myf_Size(a0),d1 ;no file no size
- .A move.l a0,fib_DiskKey(a1)
- move.l d1,fib_Size(a1) ;calc size
- add.l #1023,d1
- lsr.l #8,d1
- lsr.l #2,d1
- move.l d1,fib_NumBlocks(a1)
- moveq #2,d0
- move.b myf_Type(a0),d1
- btst #5,d1 ;copied ? -> A
- beq.s .F
- bset #4,d0
- .F btst #4,d1 ;notify ? -> P
- beq.s .G
- bset #5,d0
- .G IFD DEBUG
- btst #6,d1 ;hidden ? -> H
- beq.s .J
- bset #7,d0
- .J tst.b myf_Locks(a0)
- beq.s .H
- bmi.s .I
- bset #2,d0 ;read-locked ? -> no W
- bra.s .H
- .I bset #3,d0 ;write-locked ? -> no R
- .H ENDC
- move.l d0,fib_Protection(a1)
- move.l StartDate+0(a5),fib_DateStamp+0(a1)
- move.l StartDate+4(a5),fib_DateStamp+4(a1)
- move.l StartDate+8(a5),fib_DateStamp+8(a1)
- lea myf_Name(a0),a0
- DBUG1 txexan,a0
- lea fib_FileName(a1),a1
- moveq #106,d0
- bsr CopyChar2BSTR
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- rts
-
- AExamineNext:
- move.l dp_Arg1(a4),a2
- add.l a2,a2
- add.l a2,a2
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- move.l fib_DiskKey(a1),a0
- DBUG1 txexnx,a0
- cmp.l myl_Key(a2),a0
- bne.s .A
- move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
- tst.b myf_Type(a0)
- bmi.s .fail
- move.l myf_First-myf_Link(a0),a0
- bra.s .C
- .A move.l myf_Link(a0),a0
- .C move.w #ERROR_NO_MORE_ENTRIES,dp_Res2+2(a4)
- move.l a0,d0
- beq.s .fail
- IFND DEBUG
- btst #6,myf_Type(a0)
- bne.s .A
- ENDC
- bra ExamineObject
- .fail rts
-
- ADiskInfo1:
- move.l dp_Arg1(a4),a0
- bra.s DiskInfo
- ADiskInfo2:
- move.l dp_Arg2(a4),a0
- * ENTRY: a0=buffer (BPTR)
- DiskInfo: ;label not used globally
- add.l a0,a0
- add.l a0,a0
- move.l a0,a1
- moveq #id_SIZEOF/4-1,d0
- .D clr.l (a1)+
- dbra d0,.D
- IFD DEBUG
- move.l NumLocks(a5),id_NumSoftErrors(a0)
- ENDC
- moveq #ID_VALIDATED,d0
- tst.b WriteProtected(a5)
- beq.s .C
- moveq #ID_WRITE_PROTECTED,d0
- .C move.l d0,id_DiskState(a0)
- move.l #1024,d1
- move.l d1,id_BytesPerBlock(a0)
- lsr.l #1,d1
- move.l FileSize(a5),d0
- add.l d1,d0
- lsr.l #8,d0
- lsr.l #2,d0
- move.l d0,id_NumBlocksUsed(a0)
- move.l TotalSize(a5),d0
- add.l d1,d0
- lsr.l #8,d0
- lsr.l #2,d0
- bne.s .A
- moveq #1,d0
- .A move.l d0,id_NumBlocks(a0)
- move.l #"DOS"<<8,id_DiskType(a0)
- move.l MyVolumeBPTR(a5),id_VolumeNode(a0)
- move.l RootLock(a5),id_InUse(a0)
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- rts
-
- ACreateDir:
- move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
- tst.b WriteProtected(a5)
- bne.s .fail
- move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr DelSearchObject
- bne.s .fail
- bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
- move.l dp_Arg1(a4),d0
- bsr CreatePath
- beq.s .fail
- move.l d0,a3
- lea TempName(a5),a2
- moveq #0,d2
- bsr CreateNewObject
- beq.s .fail
- move.l d0,a2
- clr.b myf_Type(a2)
- moveq #ACCESS_WRITE,d2
- bsr CreateLock
- beq.s .fail
- move.l d0,a0
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- move.l myl_Key(a0),a0
- bsr CheckNotify
- .fail rts
-
- *******************************************************
-
- * Here are subroutines that deal with Locks and Filehandles
-
- AFHfromLock:
- move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
- move.l dp_Arg2(a4),d0
- beq.s .fail
- lsl.l #2,d0
- move.l d0,a0
- move.l myl_Key(a0),a0
- tst.b myf_Type(a0) ;do not open dirs
- bmi OpnOld
- .fail rts
-
- AChangeMode:
- move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a2
- moveq #CHANGE_FH,d1
- cmp.l d0,d1
- bne.s .A
- move.l dp_Arg1(a4),a3
- add.l a3,a3
- add.l a3,a3
- move.l fh_Arg1(a3),d0
- beq.s .fail
- move.l d0,a2
- bra.s .C
- .A moveq #CHANGE_LOCK,d1
- cmp.l d0,d1
- bne.s .fail
- .C move.l myl_Key(a2),a0
- move.b myf_Locks(a0),d0
- move.l dp_Arg3(a4),d2
- moveq #ACCESS_WRITE,d1
- cmp.l d1,d2
- bne.s .D
- cmp.b d0,d1
- beq.s .ok
- cmp.b #1,d0
- bne.s .fail
- move.b d1,myf_Locks(a0)
- bra.s .ok
- .D cmp.b d0,d1
- bne.s .E
- tst.l myl_Start(a2)
- bne.s .fail
- move.b #1,myf_Locks(a0)
- .E moveq #ACCESS_READ,d1
- .ok move.l d1,myl_Access(a2)
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- *******************************************************
-
- * Here are subroutines for notification support
-
- AAddNotify:
- move.w #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
- move.l dp_Arg1(a4),a3
- moveq #myn_Name,d0
- move.l nr_FullName(a3),a0
- .C addq.l #1,d0
- tst.b (a0)+
- bne.s .C
- bsr AllocMem
- beq.s .fail
- move.l d0,a2
- lea NotifyList(a5),a0
- move.l (a0),myn_Link(a2)
- move.l a2,(a0)
- move.l a3,myn_Request(a2)
- move.l nr_FullName(a3),a0
- lea myn_Name(a2),a1
- .D move.b (a0)+,(a1)+
- bne.s .D
- bsr UpNoti
- IFD DEBUG
- lea myn_Name(a2),a0
- DBUG4 txanoti,a2,a3,a0,d0
- ENDC
- move.l nr_Flags(a3),d1
- btst #NRB_NOTIFY_INITIAL,d1 ;initial notify ?
- beq.s .A
- tst.l d0
- beq.s .A
- move.l d0,a0
- btst #6,myf_Type(a0) ;file really exists ?
- bne.s .A
- bsr SendNotify
- .A moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- ARemoveNotify:
- move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
- move.l dp_Arg1(a4),a2
- tst.l nr_MsgCount(a2)
- bne.s .fail
- move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
- lea NotifyList(a5),a1
- .A move.l (a1),d0
- beq.s .fail
- move.l a1,a0
- move.l d0,a1
- cmp.l myn_Request(a1),a2
- bne.s .A
- move.l myn_Link(a1),myn_Link(a0)
- DBUG2 txrnoti,a1,a2
- move.l myn_Key(a1),d0
- beq.s .D
- move.l d0,a0
- bclr #4,myf_Type(a0)
- .D moveq #myn_Name,d0
- lea myn_Name(a1),a0
- .C addq.l #1,d0
- tst.b (a0)+
- bne.s .C
- bsr FreeMem
- moveq #DOS_TRUE,d0
- move.l d0,dp_Res1(a4)
- .fail rts
-
- * Update myn_Key of notification list, mainly used by CheckNotify
- * ENTRY: a0=file
- UpdateNotify:
- move.l a2,-(sp)
- lea NotifyList(a5),a2
- bra.s .A
- .C move.l d0,a2
- tst.l myn_Key(a2)
- bne.s .A
- bsr.s UpNoti
- IFD DEBUG
- beq.s .A
- lea myn_Name(a2),a0
- DBUG2 txunoti,a0,d0
- ENDC
- .A move.l (a2),d0
- bne.s .C
- move.l (sp)+,a2
- rts
-
- * Subroutine used by UpdateNotify and AddNotify
- UpNoti lea myn_Name(a2),a0
- lea TempPath(a5),a1
- moveq #MAXPATH-1,d0
- bsr CopyChar2Char
- moveq #0,d0
- bsr SearchPath
- bne.s .A
- moveq #0,d0
- bsr CalcFullName
- .A move.l d0,myn_Key(a2)
- beq.s .D
- move.l d0,a0
- bset #4,myf_Type(a0)
- .D rts
-
- * Update notification list, check it for file/dir and parent dir
- * and notify them.
- * ENTRY: a0=file
- CheckNotify:
- move.l a0,-(sp)
- IFD DEBUG
- lea myf_Name(a0),a0
- DBUG1 txcnoti,a0
- ENDC
- bsr UpdateNotify
- move.l (sp)+,a0
-
- * Check notification list for file/dir and parent dir and notify them.
- * ENTRY: a0=file
- NotifyObject:
- bsr NotifyObj
- move.l myf_Parent(a0),d1
- move.l d1,a0
- beq.s .E
- bsr NotifyObj
- .E rts
-
- * Notify object in a0, only used by NotifyObject
- NotifyObj:
- movem.l a2/a3,-(sp)
- lea NotifyList(a5),a2
- bra.s .A
- .C move.l d0,a2
- cmp.l myn_Key(a2),a0
- bne.s .A
- move.l a0,-(sp)
- move.l myn_Request(a2),a3
- bsr SendNotify
- move.l (sp)+,a0
- .A move.l (a2),d0
- bne.s .C
- movem.l (sp)+,a2/a3
- rts
-
- * Send a Notify message or set a Notify signal
- * ENTRY: a3=NotifyRequest
- SendNotify:
- btst #NRB_SEND_SIGNAL,nr_Flags+3(a3)
- beq.s .C
- move.l nr_Task(a3),a1
- IFD DEBUG
- move.l LN_NAME(a1),d0
- lea myn_Name(a2),a0
- DBUG2 txsnoti,d0,a0
- ENDC
- moveq #0,d0
- move.b nr_SignalNum(a3),d1
- bset d1,d0
- CALL Signal
- rts
-
- .C btst #NRB_SEND_MESSAGE,nr_Flags+3(a3)
- beq .D
- moveq #NotifyMessage_SIZEOF,d0
- bsr AllocMem
- beq .D
- move.l d0,a0
- move.l d0,a1
- moveq #NotifyMessage_SIZEOF/2-1,d0
- .A clr.w (a0)+
- dbra d0,.A
- move.b #NT_MESSAGE,LN_TYPE(a1)
- lea NotifyPort(a5),a0
- move.l a0,MN_REPLYPORT(a1)
- move.w #NotifyMessage_SIZEOF,MN_LENGTH(a1)
- move.l #$40000000,nm_Class(a1)
- move.w #$1234,nm_Code(a1)
- move.l a3,nm_NReq(a1)
- IFD DEBUG
- move.l a2,-(sp)
- move.l nr_Port(a3),a0
- move.l MP_SIGTASK(a0),a0
- move.l LN_NAME(a0),a0
- lea myn_Name(a2),a2
- DBUG3 txmnoti,a1,a0,a2
- move.l (sp)+,a2
- ENDC
- move.l nr_Port(a3),a0
- CALL PutMsg
- addq.l #1,nr_MsgCount(a3)
- ; btst #NRB_WAIT_REPLY,nr_Flags+3(a3)
- ; beq.s .D
- ; lea NotifyPort(a5),a0
- ; CALL WaitPort
- ; bsr GetNotify
- .D rts
-
- * Handle replies of Notify messages
- GetNotify:
- .A lea NotifyPort(a5),a0
- CALL GetMsg
- tst.l d0
- beq.s .E
- move.l d0,a1
- DBUG1 txgnoti,a1
- move.l nm_NReq(a1),a0
- subq.l #1,nr_MsgCount(a0)
- moveq #NotifyMessage_SIZEOF,d0
- bsr FreeMem
- bra.s .A
- .E rts
-
- *******************************************************
-
- *******************************************************
-
- * Following there are support subroutines for creating and deleting
- * objects and Locks.
-
- * Create a new file/dir
- * ENTRY: a2=name, a3=parent dir, d2=data size
- * EXIT: d1=offset of data, d0=new file, Z-flag for success
- CreateNewObject:
- move.w #ERROR_DISK_FULL,dp_Res2+2(a4)
- CreateNewObj: ;label used by SearchPath and CalcFullName
- movem.l d3/a2-a3,-(sp)
- move.l a2,a0
- moveq #myf_Name,d3
- .D addq.l #1,d3
- tst.b (a0)+
- bne.s .D
- addq.l #1,d3
- bclr #0,d3
- move.l d3,d0
- add.l d2,d0
- bsr AllocMem
- beq.s .fail
- move.l d0,a1
- lea myf_First(a3),a0
- .C move.l (a0),d0
- beq.s .A
- move.l d0,a0
- bra.s .C
- .A move.l a1,(a0)
- clr.l myf_Link(a1)
- move.l a3,myf_Parent(a1)
- move.l d2,myf_Size(a1)
- add.l d2,FileSize(a5)
- move.b #$80,myf_Type(a1)
- move.b d3,myf_DataOffs(a1)
- clr.b myf_Locks(a1)
- lea myf_Name(a1),a0
- .E move.b (a2)+,(a0)+
- bne.s .E
- move.l d3,d1
- move.l a1,d0
- .fail IFD DEBUG
- move.l d0,-(sp)
- lea myf_Name(a1),a2
- move.l myf_Size(a1),d0
- DBUG3 txcreat,a2,a1,d0
- move.l (sp)+,d0
- ENDC
- movem.l (sp)+,d3/a2-a3
- rts
-
- * Delete file/dir in a1, no pred. known
- * ENTRY: a1=file
- * EXIT: d0=success, Z-flag
- DeleteObj:
- move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
- move.l myf_Parent(a1),a0
- move.l myf_First(a0),d0
- sub.l a0,a0
- .C move.l a0,d1
- move.l d0,a0
- tst.l d0
- beq DelErr
- move.l myf_Link(a0),d0
- cmp.l a1,a0
- bne.s .C
-
- * Delete file/dir in a1 with pred. known
- * ENTRY: a1=file d1=pred.
- DeleteObject:
- move.l d2,-(sp)
- moveq #0,d0
- move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
- tst.b myf_Locks(a1)
- bne.s .fail
- tst.b myf_Type(a1)
- bmi.s .C
- move.w #ERROR_DIRECTORY_NOT_EMPTY,dp_Res2+2(a4)
- tst.l myf_First(a1) ;check if dir is empty
- bne.s .fail
- .C move.l myf_Link(a1),d2 ;rearrange links
- move.l d1,a0
- tst.l d1
- bne.s .A
- move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
- move.l myf_Parent(a1),d1
- beq.s .fail ;do not delete root
- move.l d1,a0
- lea myf_First-myf_Link(a0),a0
- .A move.l d2,myf_Link(a0)
- DBUG1 txdel,a1
- lea NotifyList(a5),a0
- bra.s .D
- .E move.l d0,a0
- cmp.l myn_Key(a0),a1
- bne.s .D
- clr.l myn_Key(a0) ;check notifications
- .D move.l (a0),d0
- bne.s .E
- moveq #0,d0 ;free memory
- move.b myf_DataOffs(a1),d0
- move.l myf_Size(a1),d1
- add.l d1,d0
- sub.l d1,FileSize(a5)
- bsr FreeMem
- moveq #1,d0
- .fail move.l (sp)+,d2
- DelErr tst.l d0 ;label not used globally
- rts
-
- * Create lock on file/dir given by name
- * Must preserve a3
- * ENTRY: d0=BPTR parent lock, a0=name (BSTR), d2=access mode
- * EXIT: d0=APTR lock, Z-flag
- LocateObject:
- move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
- move.l d0,d3
- bsr SearchObject
- bne.s .A
- moveq #ACCESS_READ,d0
- cmp.l d0,d2
- bne.s .C
- move.l d3,d0
- bsr CalcFullName
- bne.s .A
- .C moveq #0,d0
- bra LOfail2
- .A move.l d0,a2
- btst #6,myf_Type(a2) ;hidden ?
- bne.s .C
-
- * Create lock on file/dir given by key
- * ENTRY: a2=file, d2=access mode
- * EXIT: d0=success, Z-flag
- CreateLock:
- moveq #0,d0
- move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
- lea myf_Locks(a2),a0
- moveq #ACCESS_WRITE,d1
- cmp.l d1,d2
- bne.s .A
- tst.b (a0)
- bne.s LOfail
- move.b d1,(a0)
- bra.s .C
- .A tst.b (a0)
- bmi.s LOfail
- addq.b #1,(a0)
- .C move.w #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
- move.l #myl_SIZEOF,d0
- bsr AllocMem
- beq.s LOfail
- move.l d0,a0
- clr.l myl_Link(a0)
- clr.l myl_Pos(a0)
- clr.l myl_Data(a0)
- clr.l myl_Start(a0)
- clr.l myl_Block(a0)
- clr.l myl_BlockPos(a0)
- clr.l myl_Size(a0)
- move.l a2,myl_Key(a0)
- move.l d2,myl_Access(a0)
- move.l MyMsgPort(a5),myl_Task(a0)
- move.l MyVolumeBPTR(a5),myl_Volume(a0)
- clr.b myl_Mode(a0)
- addq.l #1,NumLocks(a5)
- LOfail IFD DEBUG
- move.l d0,d1
- lsr.l #2,d1
- lea myf_Name(a2),a0
- DBUG3 txlock,a0,d1,d2
- ENDC
- LOfail2 tst.l d0
- rts
-
- * Free lock in a1
- * ENTRY: a1=lock (APTR)
- FreeLock:
- ; move.w #ERROR_UNLOCK_ERROR,dp_Res2+2(a4)
- IFD DEBUG
- move.l a1,d0
- lsr.l #2,d0
- DBUG1 txulock,d0
- ENDC
- move.l myl_Key(a1),a0
- tst.b myf_Locks(a0)
- beq.s .A
- bmi.s .D
- subq.b #1,myf_Locks(a0)
- bra.s .A
- .D clr.b myf_Locks(a0)
- .A move.l #myl_SIZEOF,d0
- bsr FreeMem
- subq.l #1,NumLocks(a5)
- rts
-
- *******************************************************
-
- *******************************************************
-
- * Support routines for lower level memory management
-
- * ENTRY: d0=size
- * EXIT: d0=memory
- AllocMem:
- add.l d0,TotalSize(a5)
- move.l MyMemPool(a5),d1
- beq.s .A
- move.l d1,a0
- CALL AllocPooled
- bra.s .C
- .A moveq #1,d1
- CALL AllocMem
- .C tst.l d0
- rts
-
- * ENTRY: d0=size, a1=address
- FreeMem:
- sub.l d0,TotalSize(a5)
- move.l MyMemPool(a5),d1
- beq.s .A
- move.l d1,a0
- CALL FreePooled
- rts
- .A CALL FreeMem
- rts
-
- * Copy BSTR in a0 to string in a1, d0=maxlength without 0
- CopyBSTR2Char:
- add.l a0,a0
- add.l a0,a0
- moveq #0,d1
- move.b (a0)+,d1
- MIN d0,d1,D
- bra.s .C
- .A move.b (a0)+,(a1)+
- .C dbra d1,.A
- clr.b (a1)
- rts
-
- * Copy string in a0 to BSTR in a1, d0=maxlength without 0
- * EXIT: d0=BPTR
- CopyChar2BSTR:
- moveq #-1,d1
- addq.l #1,a1
- .A addq.l #1,d1
- cmp.l d0,d1
- bhs.s .C
- move.b (a0)+,(a1)+
- bne.s .A
- subq.l #1,a1
- .C clr.b (a1)
- sub.l d1,a1
- subq.l #1,a1
- move.b d1,(a1)
- move.l a1,d0
- lsr.l #2,d0
- rts
-
- CopyChar2Char:
- * Copy string in a0 to string in a1, d0=maxlength without 0
- .C move.b (a0)+,(a1)+
- beq.s .A
- subq.l #1,d0
- bne.s .C
- .A rts
-
-
- *******************************************************
-
- *******************************************************
-
- * Subroutines for path string handling following
-
- * Same as SearchObject, but deletes hidden files
- * ENTRY: a0=filename (BSTR), d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file, TempPath=name
- DelSearchObject
- bsr SearchObject
- beq.s .A
- move.l d0,a1
- btst #6,myf_Type(a1)
- beq.s .A
- bsr DeleteObject ;delete hidden file
- moveq #0,d0
- .A tst.l d0
- rts
-
- * Same as SearchPath, but creates the path if not existent
- * ENTRY: TempPath=dirname, d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- CreatePath:
- moveq #1,d1
- bra.s SearchP
-
- * Look for object with path
- * ENTRY: a0=filename (BSTR), d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file, TempPath=name
- SearchObject:
- move.l d0,-(sp)
- lea TempPath(a5),a1
- moveq #MAXPATH-1,d0
- bsr CopyBSTR2Char
- move.l (sp)+,d0
-
- * Same as SearchObject, but name is already copied to TempPath
- * ENTRY: TempPath=dirname, d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- SearchPath:
- moveq #0,d1
- SearchP movem.l d2-d7/a2-a4,-(sp) ;label not used globally
- move.l d1,d7
- lea RootDir(a5),a1
- lea TempPath(a5),a0
- .A cmp.b #":",(a0)+ ;skip volume name
- beq.s .E
- tst.b -1(a0)
- bne.s .A
- lea TempPath(a5),a0
- .D lsl.l #2,d0 ;use root or locked dir
- beq.s .E
- move.l d0,a2
- move.l myl_Key(a2),a1 ;dir represented by lock
- .E
- * label not used
- expand IFD EXPAND
- tst.b StupExpand(a5) ;expand env:appname.prefs to
- beq .A
- tst.l myf_Parent(a1) ;env:appname/appname.prefs
- bne .A ;not in rootdir ?
- move.l a0,a4
- sub.l a2,a2
- .C move.b (a4)+,d0
- beq.s .D
- cmp.b #"/",d0 ;check for "/"
- beq .A
- cmp.b #".",d0
- bne.s .C
- move.l a4,a2 ;remember "."
- bra.s .C
- .D move.l a2,d0
- beq.s .A
- sub.l a0,d0
- lea TempPath(a5),a3
- sub.l a3,a4
- add.l a4,d0
- cmp.l #MAXPATH-1,d0
- bhs.s .A
- move.l a2,a4
- lea prefstx(pc),a3 ;ends in ".prefs" ?
- .cmp1 move.b (a4)+,d0
- cmp.b (a3)+,d0
- bne.s .F
- tst.b d0
- bne.s .cmp1
- bra.s .G
- .F move.l a2,a4
- lea configtx(pc),a3 ;ends in ".config" ?
- .cmp2 move.b (a4)+,d0
- cmp.b (a3)+,d0
- bne.s .A
- tst.b d0
- bne.s .cmp2
-
- .G tst.b (a4)+
- bne.s .G
- move.l a4,a3
- sub.l a0,a3
- add.l a2,a3
- move.l a4,d0
- sub.l a0,d0
- bra.s .I
- .H move.b -(a4),-(a3)
- .I dbra d0,.H
- move.b #"/",-1(a2)
- DBUG1 txexp,a0
-
- ; move.b #"/",-1(a2) ;insert "/" instead of "."
- ; move.l a0,a3
- ;.H move.b (a3)+,d0 ;copy first part of filename
- ; move.b d0,(a2)+
- ; cmp.b #"/",d0
- ; bne.s .H
- ; move.b #".",-1(a2) ;append ".prefs"
- ; lea prefstx(pc),a3
- ;.I move.b (a3)+,(a2)+
- ; bne.s .I
- ; DBUG1 txexp,a0
- .A ENDC
- * end of expand
-
- * label not used
- * ENTRY: a0=Name, a1=parent dir; mind SP !
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- SearchName:
- .A moveq #0,d0
- .D cmp.b #"/",(a0) ;parent dir when starting with /
- bne.s .H
- move.l myf_Parent(a1),d2
- beq.s .fail
- move.l d2,a1
- addq.l #1,a0
- bra.s .D
- .H tst.b (a0) ;check for empty string
- beq.s .G
- move.l a0,a4
- moveq #0,d3
- .C addq.l #1,d3 ;look for / or end
- tst.b (a4)
- beq.s .E
- cmp.b #":",(a4)
- beq.s .fail
- cmp.b #"/",(a4)+
- bne.s .C
- .E move.b myf_Type(a1),d2
- bmi.s .fail
- btst #6,d2
- beq.s .J
- tst.l d7 ;check for CreatePath
- beq.s .fail
- clr.b myf_Type(a1) ;convert hidden to dir
- .J move.l a1,d2
- bsr SearchEntry ;search in dir
- bne.s .F
- tst.l d7 ;check for CreatePath
- beq.s .G
- movem.l d1-d3/a0/a2-a4,-(sp)
- move.l d2,a3
- move.l a0,a2
- move.l a0,a4
- subq.l #1,d3
- add.l d3,a4
- move.b (a4),d3
- clr.b (a4)
- moveq #0,d2
- bsr CreateNewObj ;create new dir
- move.b d3,(a4)
- move.l d0,a1
- movem.l (sp)+,d1-d3/a0/a2-a4
- tst.l d0
- beq.s .G
- clr.b myf_Type(a1)
- .F move.l a4,a0
- bra.s .A ;continue looking for / or end
- .G move.l a1,d0
- .fail IFD DEBUG
- lea TempPath(a5),a0
- moveq #0,d2
- tst.l d0
- beq.s .I
- move.b myf_Type(a1),d2
- .I DBUG3 txfnd,a0,d0,d2
- ENDC
- movem.l (sp)+,d2-d7/a2-a4
- tst.l d0
- rts
-
- * Look for object in dir
- * ENTRY: a0=file/dir name, a1=ptr to dir, d3=length of name
- * EXIT: a1=ptr to file or 0, Z-flag
- SearchEntry:
- moveq #0,d5
- moveq #0,d6
- move.l myf_First(a1),d0
- sub.l a1,a1
- .C move.l a1,d1
- move.l d0,a1
- tst.l d0
- beq.s .fail
- move.l myf_Link(a1),d0
- lea myf_Name(a1),a2
- move.l a0,a3
- move.l d3,d4
- bra.s .E
- .A move.b (a2)+,d5
- move.b CharTable(a5,d5.l),d5
- move.b (a3)+,d6
- move.b CharTable(a5,d6.l),d6
- cmp.b d5,d6
- bne.s .C
- .E subq.l #1,d4
- bne.s .A
- tst.b (a2)
- bne.s .C
- IFD DEBUG
- lea myf_Name(a1),a3
- DBUG1 txentry,a3
- ENDC
- .fail move.l a1,d0
- rts
-
- * Splits path with file into path=TempPath and file=TempName
- * ENRTY: TempPath=file with path
- * EXIT: TempPath=path, TempName=file
- SplitPath
- move.l a2,-(sp)
- lea TempPath(a5),a0
- move.l a0,a1
- .A tst.b (a0)+
- bne.s .A
- .D cmp.b #"/",-(a0)
- beq.s .C
- cmp.b #":",(a0)
- beq.s .C
- cmp.l a0,a1
- bne.s .D
- move.l a0,a1
- bra.s .G
- .C move.l a0,a1
- addq.l #1,a1
- .G lea TempName(a5),a2
- .E move.b (a1)+,(a2)+
- bne.s .E
- cmp.b #":",(a0)
- bne.s .F
- addq.l #1,a0
- .F clr.b (a0)
- move.l (sp)+,a2
- IFD DEBUG
- lea TempPath(a5),a0
- lea TempName(a5),a1
- DBUG2 txsplit,a0,a1
- ENDC
- rts
-
- * Evaluate full path name of object
- * Only used by CalcFullName
- * ENTRY: a1=object
- * EXIT: a0=full name (root name not included) in TempPath
- GetFullName:
- move.l d2,-(sp)
- lea TempPath+MAXPATH+MAXNAME-1(a5),a0
- clr.b (a0)
- move.w #MAXPATH+MAXNAME-1,d2
- .A move.l myf_Parent(a1),d0
- beq.s .ok
- lea myf_Name(a1),a1
- moveq #-1,d1
- .C addq.l #1,d1
- tst.b (a1)+
- bne.s .C
- subq.l #1,a1
- sub.w d1,d2
- bmi.s .ok
- tst.b (a0)
- beq.s .D
- move.b #"/",-(a0)
- subq.w #1,d2
- bra.s .D
- .E move.b -(a1),-(a0)
- .D dbra d1,.E
- move.l d0,a1
- bra.s .A
- .ok move.l (sp)+,d2
- rts
-
- * Create dir and copy file from ENVARC: if possible
- * Only used by LocateObject and UpNoti
- * ENTRY: TempPath=name, d0=BPTR parent lock
- * EXIT: d0=new file
- CalcFullName:
- movem.l d2-d6/a2-a4,-(sp)
- moveq #0,d4 ;d4=return code
- tst.b WriteProtected(a5)
- bne .fail
- tst.l Copyfrom(a5)
- beq .fail
- bsr CreatePath
- beq .fail
- move.l d0,a1
- move.l d0,a2
- move.b #$40,myf_Type(a1) ;a2=new hidden file
- bsr GetFullName
- DBUG1 txfull,a0
- lea TempPath(a5),a1
- moveq #MAXPATH-2,d0
- bsr CopyChar2BSTR
- move.l d0,d5 ;d5=BSTR full name
-
- move.l #fib_SIZEOF+fh_SIZEOF,d0
- bsr AllocMem
- beq .fail
- move.l d0,a3 ;a3=File info block
- lea fib_SIZEOF(a3),a4 ;a4=file handle
-
- move.l Copyfrom(a5),a0
- move.l dol_Lock(a0),d1
- move.l dol_List(a0),d6
- bra.s .D
- .C tst.l d6
- beq .fail2
- move.l d6,a0
- move.l (a0),d6 ;al_Next
- move.l 4(a0),d1 ;al_Lock
- .D move.l d1,CopyfromLock(a5)
- move.l d1,a0
- add.l a0,a0
- add.l a0,a0
- move.l fl_Task(a0),CopyfromPort(a5)
- move.l d5,d2
- moveq #ACCESS_READ,d3
- moveq #ACTION_LOCATE_OBJECT,d0
- bsr DoPacket
- beq .C
-
- move.l d0,d3 ;d3=lock on file
- move.l d3,d1
- move.l a3,d2
- lsr.l #2,d2
- moveq #ACTION_EXAMINE_OBJECT,d0
- bsr DoPacket
- move.l d0,-(sp)
- move.l d3,d1
- moveq #ACTION_FREE_LOCK,d0
- bsr DoPacket
- move.l (sp)+,d0
- beq.s .fail2
- tst.l fib_DirEntryType(a3)
- bmi.s .A
- clr.b myf_Type(a2) ;turn hidden into dir
- move.l a2,d4
- bra.s .fail2
-
- .A move.l a4,d1
- lsr.l #2,d1
- move.l CopyfromLock(a5),d2
- move.l d5,d3
- move.l #ACTION_FINDINPUT,d0
- bsr DoPacket
- beq.s .fail2
- movem.l a2/a3,-(sp)
- move.l fib_Size(a3),d2
- move.l myf_Parent(a2),a3
- lea myf_Name(a2),a2
- bsr CreateNewObject
- movem.l (sp)+,a2/a3
- beq.s .fail3
- move.l d0,d2
- add.l d1,d2
- move.l a2,a1
- move.l d0,a2
- move.b #$a0,myf_Type(a2)
- bsr DeleteObj
- beq.s .fail3
- move.l fh_Arg1(a4),a4
- move.l a4,d1
- move.l fib_Size(a3),d3
- moveq #ACTION_READ,d0
- bsr DoPacket
- bsr UpdateNotify
- .fail3 move.l a4,d1
- move.l #ACTION_END,d0
- bsr DoPacket
- move.l a2,d4
- .fail2 move.l a3,a1
- move.l #fib_SIZEOF+fh_SIZEOF,d0
- bsr FreeMem
- .fail move.l d4,d0
- movem.l (sp)+,d2-d6/a2-a4
- rts
-
- *******************************************************
-
- *******************************************************
-
- * Debug output support subroutines and strings following
-
- IFD DEBUG
-
- * Output one character
- RawHook move.l a6,-(sp)
- move.l 4.w,a6
- jsr _LVORawPutChar(a6)
- move.l (sp)+,a6
- rts
-
- * Wait for CTRL-C signal
- wait_c:
- movem.l d0-d1/a0-a1,-(sp)
- moveq #0,d0
- moveq #0,d1
- bset #12,d1
- jsr _LVOSetSignal(a6)
- moveq #0,d0
- bset #12,d0
- jsr _LVOWait(a6) ;wait for CTRL-C
- movem.l (sp)+,d0-d1/a0-a1
- rts
-
- IFD VERBOSE
- txstart dc.b "Handler started, A5=$%lx.",10,0
- txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld..",10,0
- txcopy dc.b "Copyfrom=$%lx.",10,0
- txpack dc.b "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
- txres dc.b "Result1=$%lx, Result2=%ld.",10,0
- txpkt dc.b " Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
- txerr1 dc.b " %ld: Unknown Action.",10,0
-
- txopeno dc.b " Oldopen lock=$%lx.",10,0
- txopenn dc.b " Newopen lock=$%lx.",10,0
- txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
- txread dc.b " Read %ld of %ld bytes, pos=%ld.",10,0
- txwrite dc.b " Wrote %ld bytes, pos=%ld, size=%ld.",10,0
- txwins dc.b " Inserted %ld bytes at %ld.",10,0
- txchng dc.b " Changed mode, pos=%ld, size=%ld.",10,0
- txseek dc.b " Seeked, filepos=%ld.",10,0
- txdel dc.b " Deleted $%lx.",10,0
-
- txlock dc.b " Locked %s=$%lx mode %ld.",10,0
- txulock dc.b " Unlocked $%lx.",10,0
- txexam dc.b " Examined file=$%lx.",10,0
- txexnx dc.b " Examined next file=$%lx.",10,0
- txfnd dc.b " Found %s=$%lx type=$%lx.",10,0
- txentry dc.b " Found entry %s.",10,0
- txsplit dc.b " Splitted ->%s,%s.",10,0
- txfull dc.b " Full name: %s.",10,0
- txexp dc.b " Expanded path to %s.",10,0
-
- txanoti dc.b " Added noti $%lx->$%lx on %s key=$%lx.",10,0
- txrnoti dc.b " Removed noti $%lx->$%lx.",10,0
- txcnoti dc.b " Checking noti on %s.",10,0
- txunoti dc.b " Updated noti on %s key=$%lx.",10,0
- txsnoti dc.b " Sent signal to %s for %s.",10,0
- txmnoti dc.b " Sent message $%lx to %s for %s.",10,0
- txgnoti dc.b " Got message $%lx.",10,0
- ENDC
-
- IFND VERBOSE
- txstart dc.b "Handler started, A5=$%lx.",10,0
- txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld.",10,0
- txcopy dc.b "Copyfrom=$%lx.",10,0
- txpack dc.b "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
- txres dc.b "Result1=$%lx, Result2=%ld.",10,0
- txpkt dc.b 0;" Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
- txerr1 dc.b " %ld: Unknown Action.",10,0
- txargs dc.b "Args: $%lx, $%lx, $%lx, $%lx.",10,0
-
- txopeno dc.b " Oldopen lock=$%lx.",10,0
- txopenn dc.b " Newopen lock=$%lx.",10,0
- txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
- txread dc.b 0;" Read %ld of %ld bytes, pos=%ld.",10,0
- txwrite dc.b 0;" Wrote %ld bytes, pos=%ld, size=%ld.",10,0
- txwins dc.b 0;" Inserted %ld bytes at %ld.",10,0
- txchng dc.b 0;" Changed mode, file=$%lx, pos=%ld, size=%ld.",10,0
- txsize dc.b 0;" Changed size, file=$%lx, oldsize=%ld, newsize=%ld.",10,0
- txseek dc.b 0;" Seeked, filepos=%ld.",10,0
- txdel dc.b " Deleted $%lx.",10,0
-
- txlock dc.b 0;" Locked %s=$%lx mode %ld.",10,0
- txulock dc.b 0;" Unlocked $%lx.",10,0
- txexam dc.b 0;" Examined file=$%lx.",10,0
- txexan dc.b 0;" Examined %s.",10,0
- txexnx dc.b 0;" Examined next file=$%lx.",10,0
- txfnd dc.b 0;" Found %s=$%lx type=$%lx.",10,0
- txentry dc.b 0;" Found entry %s.",10,0
- txsplit dc.b 0;" Splitted ->%s,%s.",10,0
- txfull dc.b 0;" Full name: %s.",10,0
- txexp dc.b " Expanded path to %s.",10,0
-
- txanoti dc.b " Added noti $%lx->$%lx on %s key=$%lx.",10,0
- txrnoti dc.b " Removed noti $%lx->$%lx.",10,0
- txcnoti dc.b 0;" Checking noti on %s.",10,0
- txunoti dc.b 0;" Updated noti on %s key=$%lx.",10,0
- txsnoti dc.b 0;" Sent signal to %s for %s.",10,0
- txmnoti dc.b 0;" Sent message $%lx to %s for %s.",10,0
- txgnoti dc.b 0;" Got message $%lx.",10,0
- ENDC
-
- ENDC
-
- *******************************************************
-
- * Alles hat ein Ende ... ;-)
-
- END
-
-